home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Space & Astronomy
/
Space and Astronomy (October 1993).iso
/
mac
/
programs
/
satrack
/
SS4EXE.ZIP
/
SEESAT4.ZIP
/
DRIVER.C
< prev
next >
Wrap
Text File
|
1992-01-05
|
15KB
|
644 lines
/*
DRIVER.C
by Paul S. Hirose, 1992 Jan 4
main module for the SEESAT satellite tracking program.
This file is in the public domain.
0 - 99
*/
#include "B:SEESAT.H" /* global header */
/* At startup, SEESAT will execute the commands in AUTOEX */
#define AUTOEX "SEESAT.BAT"
/* library functions and #defines used in this file:
atof() exit() fclose() FILE
fopen() getchar() isspace() NULL printf() strcmp()
*/
#if ECOC
extern void exit(), printf();
extern FILE *fopen();
extern double atof();
#endif
/* The HLTRUN macro is placed in the command interpreter loop in main(), and
in the prediction loop in run(). HLTRUN allows you to easily install an
abort feature for your system. I recommend doing the abort itself with
LONGJMP(reset, 1). This will return you to the command line and turn off the
batch flag, from anywhere in the program. The aborts I've provided for Laser
C and Turbo C are activated by pressing any key. */
#if ECOC
#define HLTRUN
#endif
#if LASERC
#include <osbind.h>
#define HLTRUN\
if (Bconstat(2)) {\
Bconin(2);\
LONGJMP(reset, 1);\
}
#endif
#if TURBOC
#include <conio.h>
#define HLTRUN\
if (bioskey(1)) {\
bioskey(0);\
LONGJMP(reset, 1);\
}
#endif
/*##################### STATIC FUNCTIONS #####################*/
static void
bye(), center(), exbat(),
help(), ifprn(),
offset(), prnval(), rep(), ret(),
run(), sethor(), setmag(), setmb(), setmer(),
settz(), skip(), span(),
start(), step(), stop(), xrun();
static char *s_in();
/*############################## DATA ##############################*/
static double
tf, /* end of prediction run */
delt, /* time interval between predictions */
tspan; /* length of run */
static float magbias; /* to be applied to apparent magnitude */
struct jdtim t1; /* CENTER & START values share this */
struct comd {
char *name; /* name of command */
void (*funp)(); /* ptr to function that executes it */
};
static struct comd comds[] = {
{"STEP", step},
{"START", start},
{"STOP", stop},
{"SPAN", span},
{"CENTER", center},
{"CENTRE", center},
{"RUN", run},
{"LOAD", load}, /* READEL.C */
{"OPEN", opn}, /* READEL.C */
{"INDEX", indx}, /* READEL.C */
{"NEXT", next}, /* READEL.C */
{"SUN", dusk}, /* ASTRO.C */
{"MOON", moon}, /* ASTRO.C */
{"PARA", parall}, /* ASTRO.C */
{"PRINT?", ifprn},
{"REPEAT", rep},
{"SKIP", skip},
{"EX", exbat},
{"RET", ret},
{"AOP", aop}, /* READEL.C */
{"B", b}, /* READEL.C */
{"E", ein}, /* READEL.C */
{"EPOCH", epoc}, /* READEL.C */
{"I", inc}, /* READEL.C */
{"MA", ma}, /* READEL.C */
{"MM", mm}, /* READEL.C */
{"MMDOT", setnd}, /* READEL.C */
{"MMDOTDOT", setndd}, /* READEL.C */
{"NAME", setnam}, /* READEL.C */
{"RAAN", raan}, /* READEL.C */
{"ACTUAL", setact}, /* READEL.C */
{"NOMINAL", setnom}, /* READEL.C */
{"MAG", setmag},
{"MAGBIAS", setmb},
{"OFFSET", offset},
{"LAT", setlat}, /* ASTRO.C */
{"LON", setlon}, /* ASTRO.C */
{"HEIGHT", seth}, /* ASTRO.C */
{"ZONE", settz},
#if ENPRE
{"PRECESS", setep}, /* ASTRO.C */
#endif
{"LENGTH", setlen}, /* READEL.C */
{"MERIDIAN", setmer},
{"ALL", sethor},
#if ECOC == 0
{"HELP", help},
#endif
{"EXIT", bye},
{NULL}
};
static char *nullp = NULL; /* constant */
static char **ptok0; /* points to start of cmd line */
static FILE *batfp; /* batch file */
/* flags; set/reset by the CENTER, SPAN, START, STOP commands */
static char fcenter, fspan, fstart, fstop;
/* this flag used by autom(), set by run() when a prediction is printed */
static char fvis;
static char fbatch; /* batch mode flag */
/*############################## CODE ##############################*/
main()
{
struct comd *comdp;
char *cp1, *cp2;
ETEST((0, 1, 3, &pi)); /* dummy call to get control of brkpt */
#if ECOC
printf("SEESAT (SGP) %s by Paul Hirose\n", vers);
#else
printf("SEESAT (SGP4) %s by Paul Hirose\n", vers);
#endif
/* Ecosoft C doesn't allow negative initializers! */
xj3 = -.253881e-5;
xj4 = -1.65597e-6;
/* Attempt to open the auto-execute batch file. Setting fbatch will
redirect command input to the file. */
if (batfp = fopen(AUTOEX, "r"))
fbatch = '\001'; /* set batch flag */
/* Execution is vectored back here for all errors */
if (SETJMP(reset))
/* returned from a longjmp(); turn off batch file flag */
fbatch = '\000';
tokp = &nullp; /* clear command line */
for (;;) { /* main loop */
HLTRUN /* optional abort macro */
while (*tokp == NULL) { /* cmd line exhausted */
tok();
ptok0 = tokp;
}
cp1 = *tokp; /* point to first command */
/* Find the command in the comds[] table, execute the
corresponding function */
for (comdp = comds; (cp2 = comdp->name) && strcmp(cp1, cp2);
++comdp)
;
if (cp2) { /* found command; execute */
++tokp; /* point to first arg */
(*comdp->funp)();
++tokp; /* point to next command */
} else {
printf("%s: BAD COMMAND\n", cp1);
LONGJMP(reset, 1);
} } }
static void
bye()
{
hfree(); /* release index space */
exit(0);
}
static void
center()
{
tokjum(&t1); /* load t1 with CENTER value */
fcenter = '\001';
fstop = fstart = '\000'; /* start & stop flags */
xrun();
}
static void
exbat()
/* Execute as a batch file the next token on the command line */
{
if (batfp) /* a batch file is already open */
fclose(batfp);
if ((batfp = fopen(*tokp, "r")) == NULL) {
printf("CAN'T OPEN %s\n", *tokp);
LONGJMP(reset, 1);
}
fbatch = '\001';
}
#if ECOC == 0
static void
help()
{
printf("HELP EXIT RUN INDEX NEXT MERIDIAN ALL PRINT? REPEAT \
SKIP RET : no argument\n\n");
printf("STEP SPAN OFFSET ZONE : <time>\n");
printf(" <time> = hhmm:ss.sss...\n");
printf(" seconds optional, leading zeros optional, \
negative sign allowed\n");
printf(" ZONE = local - UTC\n\n");
printf("START STOP CENTER CENTRE PARA PRECESS MOON SUN \
ACTUAL NOMINAL : <date time>\n");
printf(" <date time> = yyyy mmm dd hhmm:ss.sss... \
example: 1992 Jan 4 1830\n\n");
printf("OPEN EX : <filename>\n");
printf("NAME LOAD : <satellite name>\n");
printf("LENGTH <1 - 22>\n");
printf("EPOCH <NORAD epoch>\n");
printf(" example: EPOCH 91032.78295309\n\n");
printf("AOP B E I MA MM MMDOT MMDOTDOT RAAN MAG MAGBIAS \
LAT LON HEIGHT : <number>\n");
printf(" integer, fixed point, or exponential format allowed\n");
printf(" south lat & west lon are negative, height = kilometers\n");
--tokp; /* token pointer */
}
#endif
static void
ifprn()
/* Causes next command to be executed if the print flag is true. Else,
skip next command. */
{
if (fvis)
--tokp;
}
static void
offset()
/* Apply a time offset to epoch of elements. Do not set iflag since
initialization is independent of time. */
{
toffs = atomin(*tokp);
}
static void
prnval(time)
double time; /* local time */
/* All tabular data from a prediction run is printed here. Except for local
time of day, all data comes from global variables in SEESAT.H. */
{
char **cpp;
/* time, azimuth, elevation. */
printf("%s %3d%3d ", timstr(time),
(int) (azel.x * ra2de + .5),
(int) (azel.y * ra2de + .5));
/* Right Ascension, declination. */
cpp = degdms(2, radec.x / twopi * 24.);
printf("%2sh%2sm ", cpp[0], cpp[1]);
cpp = degdms(1, radec.y * ra2de);
printf("%3s %2s' ", cpp[0], cpp[1]);
/* slant range, sun elevation at satellite */
printf("%5ld %3d ", (long int) (radec.z * xkmper), elsusa);
/* apparent magnitude. Flag relative mag with '*'. */
printf("%c%4.1f ", mflag ? ' ' : '*', apmag + magbias);
/* altitude */
printf("%5ld ", (long int) (latlon.z * xkmper));
/* latitude */
printf("%4.1f%c ", FABS(latlon.y) * ra2de,
(latlon.y >= 0.) ? 'N' : 'S');
/* longitude */
printf("%5.1f%c\n", FABS(latlon.x) * ra2de,
(latlon.x >= 0.) ? 'E' : 'W');
}
static void
rep()
/* causes re-execution of the command line */
{
tokp = ptok0 - 1;
}
static void
ret()
/* toggle the batch mode flag, disregard rest of command line, get next
command line */
{
if (fbatch)
fbatch = '\000';
else
/* set fbatch only if a batch file is open */
fbatch = batfp != NULL;
tok();
--tokp;
}
static void
run()
/* Execute prediction run */
{
double tsince, mins, temp;
long int jd;
unsigned int count; /* no. of predictions */
static char mode;
fvis = '\000'; /* clear "visible flag" */
if (xno == 0.) {
printf("NO ELEMENTS\n");
LONGJMP(reset, 1);
}
/* jd & mins are local time */
jd = t1.jd;
mins = t1.time;
/* set mode */
if (fstart && fstop)
mode = 1;
else if (fspan)
if (fstart)
mode = 3;
else if (fcenter)
mode = 2;
fstart = fstop = fspan = fcenter = '\000';
/* tsince = CENTER or START time (whichever was given last) */
tsince = t1.jd * xmnpda - 720. + t1.time - tzone;
/* establish the parameters of the run, according to current mode */
switch (mode) {
case 1: /* start stop */
temp = tf - tsince; /* length of run */
if (temp < 0.) {
printf("STOP < START\n");
LONGJMP(reset, 1);
}
break;
case 2:
temp = .5 * tspan;
mins -= temp;
while (mins < 0.) { /* start on previous day */
mins += xmnpda;
--jd;
} tsince -= temp; /* was initially CENTER value */
/* fall thru to next case */
case 3: /* start span */
temp = tspan;
break;
default:
printf("NOT ENOUGH RUN PARAMETERS\n");
LONGJMP(reset, 1);
}
if (delt == 0.) { /* zero span */
printf("STEP = 0\n");
LONGJMP(reset, 1);
}
count = temp / delt + 1.95; /* no. of predictions */
tsince -= epoch;
printf("%s ", name); /* satellite name */
printf("%s", jdstr(jd)); /* start date */
if (toffs)
printf(" offset = %s", timstr(toffs));
printf("\n");
printf(" time az el R.A. dec range sun mag alt la\
t lon\n");
do {
HLTRUN /* optional run abort function */
if (mins >= xmnpda) { /* crossed midnight */
mins -= xmnpda;
printf("%s\n", jdstr(++jd)); /* print new date */
}
FTEST((1, 1, 2, &tsince));
MODEL(tsince - toffs); /* call prediction model */
DTEST((2, 1, &elsusa));
if (xyztop(tsince + epoch)) {
/* above horizon; print line of data */
FTEST((3, 1, 2, &mins));
prnval(mins);
fvis = '\001'; /* set visible flag */
} mins += delt;
tsince += delt;
} while (--count);
--tokp; /* because this cmd takes no args */
}
static char *
s_in(prompt, buffer)
char *prompt, *buffer;
/* Prints prompt[] on console, puts typed string in buffer[]. Backspacing
will correct typing mistakes. Will not allow backspacing past the start of
buffer. Returns pointer to buffer. */
{
static char c, *ptr, last;
for (ptr = prompt; *ptr; ++ptr)
; /* point to terminating null of prompt */
last = *(ptr - 1); /* fetch char before the null */
printf("%s", prompt);
ptr = buffer;
while ((c = getchar()) != '\n')
if (c == '\b')
if (ptr == buffer)
printf("%c", last);
else
--ptr;
else
*ptr++ = c;
*ptr = '\0';
return buffer;
}
static void
sethor()
/* toggles the flag that suppress printout of predictions below horizon */
{
aflag = !aflag;
--tokp; /* because this cmd takes no args */
}
static void
setmag()
/* set absolute magnitude */
{
abmag = atof(*tokp);
mflag = '\001'; /* set magnitude flag */
}
static void
setmb()
/* set magnitude bias */
{
magbias = atof(*tokp);
}
static void
setmer()
/* toggles flag that selects Greenwich or local meridian for longitude
readout. */
{
printf("%s meridian\n", (gflag = !gflag) ? "Greenwich" : "local");
--tokp; /* because this cmd takes no args */
}
static void
settz()
/* sets time zone (local time - UTC) */
{
tzone = atomin(*tokp);
}
static void
skip()
/* causes next command to be skipped */
{
}
static void
span()
{
tspan = atomin(*tokp);
fspan = '\001'; /* set flag */
xrun();
}
static void
start()
{
tokjum(&t1); /* load struct with START time */
fstart = '\001'; /* set flag */
fcenter = '\000'; /* center flag */
xrun();
}
static void
step()
{
delt = atomin(*tokp);
xrun();
}
static void
stop()
{
tf = tokmin();
fstop = '\001'; /* set flag */
fcenter = '\000'; /* center flag */
xrun();
}
void
tok()
/* Inputs a command line from console (or batch file, if fbatch true).
String is converted to upper case. Each ' ' in the string is replaced with
'\0' & successive members of tokens[] point to the sub-strings ("tokens")
thus created. A character sequence containing spaces is considered a single
token if it's enclosed in quotes (the quotes will not become part of the
token). End of tokens[] is marked by NULL. On exit, tokp points to
tokens[0], i.e., it works like the traditional C variable argv. */
{
char *cptr;
char c;
int notok; /* flag; 1 = not in a token */
static char
*tokens[15], /* pointers to cmd line tokens */
buffer[85]; /* command line buffer */
if (fbatch)
if (getlin(buffer, 85, batfp) == 0) {
printf("end of batch file\n");
fclose(batfp);
batfp = NULL; /* to indicate no batch file open */
LONGJMP(reset, 1);
} else /* show the batch file line */
printf(">%s\n", buffer);
else {
/* display '>', get command line from keyboard */
s_in(">", buffer);
}
stoup(buffer);
tokp = tokens; /* point to 1st element of tokens[] */
notok = 1; /* set "not in token" flag true */
for (cptr = buffer; c = *cptr; ++cptr)
if (isspace(c)) {
notok = 1;
*cptr = '\0'; /* replace ' ' with '\0' */
} else if (notok) { /* first char of a token */
notok = 0;
if (c != '"')
*tokp++ = cptr;
else { /* quoted token */
*tokp++ = ++cptr;
while ((c = *++cptr) && c != '"')
/* find closing '"' or end of string */
;
if (c) /* found '"' */
*cptr = '\0';
else /* found '\0' */
--cptr;
} }
*tokp = NULL; /* terminate tokens[] */
tokp = tokens;
}
static void
xrun()
/* do a run if command line is exhausted */
{
if (tokp[1] == NULL) {
run();
++tokp; /* run() decremented it */
} }
dicate no batch file open */
LONGJMP(reset, 1);
} else /* show the batch file line */
printf(">%s\n", buffer);